<!DOCTYPE HTML>
<html lang="zh-Hans" class="sidebar-visible no-js light">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Common Rust Lifetime Misconceptions - Rust 优秀博文</title>


        <!-- Custom HTML head -->
        
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../../favicon.svg">
        <link rel="shortcut icon" href="../../favicon.png">
        <link rel="stylesheet" href="../../css/variables.css">
        <link rel="stylesheet" href="../../css/general.css">
        <link rel="stylesheet" href="../../css/chrome.css">
        <link rel="stylesheet" href="../../css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../../fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../../highlight.css">
        <link rel="stylesheet" href="../../tomorrow-night.css">
        <link rel="stylesheet" href="../../ayu-highlight.css">

        <!-- Custom theme stylesheets -->

    </head>
    <body>
        <!-- Provide site root to javascript -->
        <script type="text/javascript">
            var path_to_root = "../../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script type="text/javascript">
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var html = document.querySelector('html');
            var sidebar = 'hidden';
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">1.</strong> 类型系统</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow.html"><strong aria-hidden="true">1.1.</strong> Rust Concept Clarification Deref vs AsRef vs Borrow vs Cow</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Deref_AsRef_Borrow_Cow释义.html"><strong aria-hidden="true">1.2.</strong> Deref AsRef Borrow Cow 释义</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然/Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然.html"><strong aria-hidden="true">1.3.</strong> Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust的Cow类型有什么用？详解Cow及其用途/Rust的Cow类型有什么用？详解Cow及其用途.html"><strong aria-hidden="true">1.4.</strong> Rust的Cow类型有什么用？详解Cow及其用途</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/判别Fn、FnMut、FnOnce的标准/判别Fn、FnMut、FnOnce的标准.html"><strong aria-hidden="true">1.5.</strong> 判别Fn、FnMut、FnOnce的标准</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/一行代码告诉你内部可变性的真相(UnsafeCell)/一行代码告诉你内部可变性的真相(UnsafeCell).html"><strong aria-hidden="true">1.6.</strong> 一行代码告诉你内部可变性的真相(UnsafeCell)</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Tour_of_Rust's_Standard_Library_Traits/Tour_of_Rust's_Standard_Library_Traits.html"><strong aria-hidden="true">1.7.</strong> Tour of Rust's Standard Library Traits</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/逆变、协变与子类型，以及Rust/逆变、协变与子类型，以及Rust.html"><strong aria-hidden="true">1.8.</strong> 逆变、协变与子类型，以及Rust</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust自引用结构、Pin与Unpin/Rust自引用结构、Pin与Unpin.html"><strong aria-hidden="true">1.9.</strong> Rust自引用结构、Pin与Unpin</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/为什么Rust需要Pin,Unpin/为什么Rust需要Pin,Unpin.html"><strong aria-hidden="true">1.10.</strong> 译：为什么 Rust 需要 Pin, Unpin ？</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/定海神针Pin和Unpin/定海神针Pin和Unpin.html"><strong aria-hidden="true">1.11.</strong> 译：定海神针 Pin 和 Unpin</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/sizedness-in-rust/sizedness-in-rust.html"><strong aria-hidden="true">1.12.</strong> Sizedness in Rust</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust生命周期集大成者PhantomData〈T〉/Rust生命周期集大成者PhantomData〈T〉.html"><strong aria-hidden="true">1.13.</strong> Rust生命周期集大成者 PhantomData&lt;T&gt;</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用Rust做类型体操_Part_0.html"><strong aria-hidden="true">1.14.</strong> 数据库表达式执行的黑魔法：用Rust做类型体操 Part 0</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：GAT实现引用类型关联_Part_1.html"><strong aria-hidden="true">1.15.</strong> 数据库表达式执行的黑魔法：GAT实现引用类型关联 Part 1</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用HRTB写bound_Part_2.html"><strong aria-hidden="true">1.16.</strong> 数据库表达式执行的黑魔法：用HRTB写bound Part 2</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用Rust做类型体操之用宏展开重复代码_Part_3_&_4.html"><strong aria-hidden="true">1.17.</strong> 数据库表达式执行的黑魔法：用Rust做类型体操之用宏展开重复代码 Part 3 & 4</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：与Rust编译器斗智斗勇之表达式向量化_Part_5_&_6.html"><strong aria-hidden="true">1.18.</strong> 数据库表达式执行的黑魔法：与Rust编译器斗智斗勇之表达式向量化 Part 5 & 6</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：在Rust中用宏关联逻辑类型和实际类型_Part_7.html"><strong aria-hidden="true">1.19.</strong> 数据库表达式执行的黑魔法：在Rust中用宏关联逻辑类型和实际类型 Part 7</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">2.</strong> 生命周期</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../02_生命周期/Rust中的生命周期——从StrSplit实例说开去/Rust中的生命周期——从StrSplit实例说开去.html"><strong aria-hidden="true">2.1.</strong> Rust中的生命周期——从StrSplit实例说开去</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/与ChatGPT深度对话来学Rust生命周期/与ChatGPT深度对话来学Rust生命周期.html"><strong aria-hidden="true">2.2.</strong> 与ChatGPT深度对话来学Rust生命周期</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——early_bound与late_bound（1）/进击的Rust生命周期——early_bound与late_bound（1）.html"><strong aria-hidden="true">2.3.</strong> 进击的Rust生命周期——early_bound与late_bound（1）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——early_bound与late_bound（2）/进击的Rust生命周期——early_bound与late_bound（2）.html"><strong aria-hidden="true">2.4.</strong> 进击的Rust生命周期——early_bound与late_bound（2）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（1）/进击的Rust生命周期——一力降十会的MIR（1）.html"><strong aria-hidden="true">2.5.</strong> 进击的Rust生命周期——一力降十会的MIR（1）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（2）/进击的Rust生命周期——一力降十会的MIR（2）.html"><strong aria-hidden="true">2.6.</strong> 进击的Rust生命周期——一力降十会的MIR（2）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/Common_Rust_Lifetime_Misconceptions/Common_Rust_Lifetime_Misconceptions.html" class="active"><strong aria-hidden="true">2.7.</strong> Common Rust Lifetime Misconceptions</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/Rust生命周期常见误区/Rust生命周期常见误区.html"><strong aria-hidden="true">2.8.</strong> 译：Rust生命周期常见误区</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">3.</strong> 无畏并发</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../05_无畏并发/简单写个Rust无锁队列/简单写个Rust无锁队列.html"><strong aria-hidden="true">3.1.</strong> 简单写个Rust无锁队列</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——混合自旋锁/进击的Rust多线程——混合自旋锁.html"><strong aria-hidden="true">3.2.</strong> 进击的Rust多线程——混合自旋锁</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/An_unsafe_tour_of_Rust's_Send_and_Sync/An_unsafe_tour_of_Rust's_Send_and_Sync.html"><strong aria-hidden="true">3.3.</strong> An unsafe tour of Rust's Send and Sync</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——Send与Sync/进击的Rust多线程——Send与Sync.html"><strong aria-hidden="true">3.4.</strong> 进击的Rust多线程——Send与Sync</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——离经叛道的PhantomData/进击的Rust多线程——离经叛道的PhantomData.html"><strong aria-hidden="true">3.5.</strong> 进击的Rust多线程——离经叛道的PhantomData</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust_Async_Pin概念解析/Rust_Async_Pin概念解析.html"><strong aria-hidden="true">3.6.</strong> Rust Async: Pin概念解析</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust和C++的并发库对比/Rust和C++的并发库对比.html"><strong aria-hidden="true">3.7.</strong> 译：Rust 和 C++ 的并发库对比</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust原子类型和内存排序/Rust原子类型和内存排序.html"><strong aria-hidden="true">3.8.</strong> Rust原子类型和内存排序</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">4.</strong> 网络编程</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../06_网络编程/从编解码层面理解WebSocket_手写一个WebSocket/从编解码层面理解WebSocket_手写一个WebSocket.html"><strong aria-hidden="true">4.1.</strong> 从编解码层面理解WebSocket 手写一 个WebSocket</a></li><li class="chapter-item expanded "><a href="../../06_网络编程/透过Rust探索系统的本原：网络篇/透过Rust探索系统的本原：网络篇.html"><strong aria-hidden="true">4.2.</strong> 透过Rust探索系统的本原：网络篇</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">5.</strong> 轮子系列</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../07_轮子系列/700行Rust写一个内存分配器/700行Rust写一个内存分配器.html"><strong aria-hidden="true">5.1.</strong> 700行Rust写一个内存分配器</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/Rust：网络库的实现思路/Rust：网络库的实现思路.html"><strong aria-hidden="true">5.2.</strong> Rust：网络库的实现思路</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/Rust异步运行时基础部件/Rust异步运行时基础部件.html"><strong aria-hidden="true">5.3.</strong> Rust异步运行时基础部件</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（1）.html"><strong aria-hidden="true">5.4.</strong> 使用Rust+epoll编写异步IO框架（1）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（2）.html"><strong aria-hidden="true">5.5.</strong> 使用Rust+epoll编写异步IO框架（2）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（3）.html"><strong aria-hidden="true">5.6.</strong> 使用Rust+epoll编写异步IO框架（3）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day1.html"><strong aria-hidden="true">5.7.</strong> 用rust从零开发一套web框架：day1</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day2.html"><strong aria-hidden="true">5.8.</strong> 用rust从零开发一套web框架：day2</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day3.html"><strong aria-hidden="true">5.9.</strong> 用rust从零开发一套web框架：day3</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day4.html"><strong aria-hidden="true">5.10.</strong> 用rust从零开发一套web框架：day4</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day5.html"><strong aria-hidden="true">5.11.</strong> 用rust从零开发一套web框架：day5</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">6.</strong> 奇技淫巧</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Copy-On-Write是不是优化？/Copy-On-Write是不是优化？.html"><strong aria-hidden="true">6.1.</strong> 译：Copy-On-Write是不是优化？</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/揭秘神奇的Rust_Axum风格的函数实现/揭秘神奇的Rust_Axum风格的函数实现.html"><strong aria-hidden="true">6.2.</strong> 译：揭秘神奇的 Rust Axum 风格的函数实现</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/“变长参数”函数与回调/“变长参数”函数与回调.html"><strong aria-hidden="true">6.3.</strong> “变长参数”函数与回调</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Rust字符串格式化的幕后：format_args!()/Rust字符串格式化的幕后：format_args!().html"><strong aria-hidden="true">6.4.</strong> 译：Rust字符串格式化的幕后：format_args!()</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/给Rust带来一点C++特产/给Rust带来一点C++特产.html"><strong aria-hidden="true">6.5.</strong> 给Rust带来一点C++特产</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/一步步实现_Rust_Bevy_ECS_的_System_简化版本/一步步实现_Rust_Bevy_ECS_的_System_简化版本.html"><strong aria-hidden="true">6.6.</strong> 一步步实现 Rust Bevy ECS 的 System 简化版本</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Exploring_Design_Patterns_in_Rust_with_Algorithmic_Trading_Examples/Exploring_Design_Patterns_in_Rust_with_Algorithmic_Trading_Examples.html"><strong aria-hidden="true">6.7.</strong> Exploring Design Patterns in Rust with Algorithmic Trading Examples</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">7.</strong> 源码分析</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：bytes源码分析/Rust并发：bytes源码分析.html"><strong aria-hidden="true">7.1.</strong> Rust并发：bytes源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：标准库Arc源码分析/Rust并发：标准库Arc源码分析.html"><strong aria-hidden="true">7.2.</strong> Rust并发：标准库Arc源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：标准库sync_Once源码分析/Rust并发：标准库sync_Once源码分析.html"><strong aria-hidden="true">7.3.</strong> Rust并发：标准库sync::Once源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust源码阅读：引用计数Rc/Rust源码阅读：引用计数Rc.html"><strong aria-hidden="true">7.4.</strong> Rust源码阅读：引用计数Rc</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust源码阅读：Cell、RefCell与内部可变性/Rust源码阅读：Cell、RefCell与内部可变性.html"><strong aria-hidden="true">7.5.</strong> Rust源码阅读： Cell、RefCell与内部可变性</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/关于_Rust_的_UnsafeCell、Cell_与_RefCell/关于_Rust_的_UnsafeCell、Cell_与_RefCell.html"><strong aria-hidden="true">7.6.</strong> 关于 Rust 的 UnsafeCell、Cell 与 RefCell</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust_Async_async-stream源码分析/Rust_Async_async-stream源码分析.html"><strong aria-hidden="true">7.7.</strong> Rust Async: async-stream源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/走进Tokio的异步世界/走进Tokio的异步世界.html"><strong aria-hidden="true">7.8.</strong> 走进 Tokio 的异步世界</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/tokio.rs_runtime的实现/tokio.rs_runtime的实现.html"><strong aria-hidden="true">7.9.</strong> tokio.rs runtime 的实现</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_internals/Tokio_internals.html"><strong aria-hidden="true">7.10.</strong> Tokio internals</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_internals/译文：Tokio內部机制.html"><strong aria-hidden="true">7.11.</strong> 译：Tokio 内部机制</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust_Axum_HTTP_框架的架构分析/Rust_Axum_HTTP_框架的架构分析.html"><strong aria-hidden="true">7.12.</strong> Rust Axum HTTP 框架的架构分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/安利一个Rust_Game_Engine：Bevy--ECS部分/安利一个Rust_Game_Engine：Bevy--ECS部分.html"><strong aria-hidden="true">7.13.</strong> 安利一个Rust Game Engine：Bevy--ECS部分</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_解析之任务调度/Tokio_解析之任务调度.html"><strong aria-hidden="true">7.14.</strong> Tokio 解析之任务调度</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">8.</strong> 生态观察</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../11_生态观察/Rust_web_frameworks_have_subpar_error_reporting/Rust_web_frameworks_have_subpar_error_reporting.html"><strong aria-hidden="true">8.1.</strong> Rust web frameworks have subpar error reporting</a></li><li class="chapter-item expanded "><a href="../../11_生态观察/SeaORM：要做Rust版本的ActiveRecord/SeaORM：要做Rust版本的ActiveRecord.html"><strong aria-hidden="true">8.2.</strong> SeaORM：要做Rust版本的ActiveRecord</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">9.</strong> 死灵终极</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_总述.html"><strong aria-hidden="true">9.1.</strong> 译：Learn Rust the Dangerous Way 总述</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_0.html"><strong aria-hidden="true">9.2.</strong> 译：Learn Rust the Dangerous Way 0</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_1.html"><strong aria-hidden="true">9.3.</strong> 译：Learn Rust the Dangerous Way 1</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_2.html"><strong aria-hidden="true">9.4.</strong> 译：Learn Rust the Dangerous Way 2</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_3.html"><strong aria-hidden="true">9.5.</strong> 译：Learn Rust the Dangerous Way 3</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_4.html"><strong aria-hidden="true">9.6.</strong> 译：Learn Rust the Dangerous Way 4</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_5.html"><strong aria-hidden="true">9.7.</strong> 译：Learn Rust the Dangerous Way 5</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（一）.html"><strong aria-hidden="true">9.8.</strong> Unsafe Rust 随堂小测（一）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（二）.html"><strong aria-hidden="true">9.9.</strong> Unsafe Rust 随堂小测（二）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（三）.html"><strong aria-hidden="true">9.10.</strong> Unsafe Rust 随堂小测（三）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测参考答案.html"><strong aria-hidden="true">9.11.</strong> Unsafe Rust 随堂小测参考答案</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky bordered">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Rust 优秀博文</h1>

                    <div class="right-buttons">
                        <a href="../../print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script type="text/javascript">
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="common-rust-lifetime-misconceptions"><a class="header" href="#common-rust-lifetime-misconceptions">Common Rust Lifetime Misconceptions</a></h1>
<p>作者：<a href="https://github.com/pretzelhammer">https://github.com/pretzelhammer</a></p>
<p>原载：<a href="https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md">https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md</a></p>
<p><em>19 May 2020 · #rust · #lifetimes</em></p>
<p><strong>Table of Contents</strong></p>
<ul>
<li><a href="#intro">Intro</a></li>
<li><a href="#the-misconceptions">The Misconceptions</a>
<ul>
<li><a href="#1-t-only-contains-owned-types">1) <code>T</code> only contains owned types</a></li>
<li><a href="#2-if-t-static-then-t-must-be-valid-for-the-entire-program">2) if <code>T: 'static</code> then <code>T</code> must be valid for the entire program</a></li>
<li><a href="#3-a-t-and-t-a-are-the-same-thing">3) <code>&amp;'a T</code> and <code>T: 'a</code> are the same thing</a></li>
<li><a href="#4-my-code-isnt-generic-and-doesnt-have-lifetimes">4) my code isn't generic and doesn't have lifetimes</a></li>
<li><a href="#5-if-it-compiles-then-my-lifetime-annotations-are-correct">5) if it compiles then my lifetime annotations are correct</a></li>
<li><a href="#6-boxed-trait-objects-dont-have-lifetimes">6) boxed trait objects don't have lifetimes</a></li>
<li><a href="#7-compiler-error-messages-will-tell-me-how-to-fix-my-program">7) compiler error messages will tell me how to fix my program</a></li>
<li><a href="#8-lifetimes-can-grow-and-shrink-at-run-time">8) lifetimes can grow and shrink at run-time</a></li>
<li><a href="#9-downgrading-mut-refs-to-shared-refs-is-safe">9) downgrading mut refs to shared refs is safe</a></li>
<li><a href="#10-closures-follow-the-same-lifetime-elision-rules-as-functions">10) closures follow the same lifetime elision rules as functions</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#discuss">Discuss</a></li>
<li><a href="#notifications">Notifications</a></li>
<li><a href="#further-reading">Further Reading</a></li>
</ul>
<h2 id="intro"><a class="header" href="#intro">Intro</a></h2>
<p>I've held all of these misconceptions at some point and I see many beginners struggle with these misconceptions today. Some of my terminology might be non-standard, so here's a table of shorthand phrases I use and what I intend for them to mean.</p>
<div class="table-wrapper"><table><thead><tr><th>Phrase</th><th>Shorthand for</th></tr></thead><tbody>
<tr><td><code>T</code></td><td>1) a set containing all possible types <em>or</em><br>2) some type within that set</td></tr>
<tr><td>owned type</td><td>some non-reference type, e.g. <code>i32</code>, <code>String</code>, <code>Vec</code>, etc</td></tr>
<tr><td>1) borrowed type <em>or</em><br>2) ref type</td><td>some reference type regardless of mutability, e.g. <code>&amp;i32</code>, <code>&amp;mut i32</code>, etc</td></tr>
<tr><td>1) mut ref <em>or</em><br>2) exclusive ref</td><td>exclusive mutable reference, i.e. <code>&amp;mut T</code></td></tr>
<tr><td>1) immut ref <em>or</em><br>2) shared ref</td><td>shared immutable reference, i.e. <code>&amp;T</code></td></tr>
</tbody></table>
</div>
<h2 id="the-misconceptions"><a class="header" href="#the-misconceptions">The Misconceptions</a></h2>
<p>In a nutshell: A variable's lifetime is how long the data it points to can be statically verified by the compiler to be valid at its current memory address. I'll now spend the next ~6500 words going into more detail about where people commonly get confused.</p>
<h3 id="1-t-only-contains-owned-types"><a class="header" href="#1-t-only-contains-owned-types">1) <code>T</code> only contains owned types</a></h3>
<p>This misconception is more about generics than lifetimes but generics and lifetimes are tightly intertwined in Rust so it's not possible to talk about one without also talking about the other. Anyway:</p>
<p>When I first started learning Rust I understood that <code>i32</code>, <code>&amp;i32</code>, and <code>&amp;mut i32</code> are different types. I also understood that some generic type variable <code>T</code> represents a set which contains all possible types. However, despite understanding both of these things separately, I wasn't able to understand them together. In my newbie Rust mind this is how I thought generics worked:</p>
<div class="table-wrapper"><table><thead><tr><th></th><th></th><th></th><th></th></tr></thead><tbody>
<tr><td><strong>Type Variable</strong></td><td><code>T</code></td><td><code>&amp;T</code></td><td><code>&amp;mut T</code></td></tr>
<tr><td><strong>Examples</strong></td><td><code>i32</code></td><td><code>&amp;i32</code></td><td><code>&amp;mut i32</code></td></tr>
</tbody></table>
</div>
<p><code>T</code> contains all owned types. <code>&amp;T</code> contains all immutably borrowed types. <code>&amp;mut T</code> contains all mutably borrowed types. <code>T</code>, <code>&amp;T</code>, and <code>&amp;mut T</code> are disjoint finite sets. Nice, simple, clean, easy, intuitive, and completely totally wrong. This is how generics actually work in Rust:</p>
<div class="table-wrapper"><table><thead><tr><th></th><th></th><th></th><th></th></tr></thead><tbody>
<tr><td><strong>Type Variable</strong></td><td><code>T</code></td><td><code>&amp;T</code></td><td><code>&amp;mut T</code></td></tr>
<tr><td><strong>Examples</strong></td><td><code>i32</code>, <code>&amp;i32</code>, <code>&amp;mut i32</code>, <code>&amp;&amp;i32</code>, <code>&amp;mut &amp;mut i32</code>, ...</td><td><code>&amp;i32</code>, <code>&amp;&amp;i32</code>, <code>&amp;&amp;mut i32</code>, ...</td><td><code>&amp;mut i32</code>, <code>&amp;mut &amp;mut i32</code>, <code>&amp;mut &amp;i32</code>, ...</td></tr>
</tbody></table>
</div>
<p><code>T</code>, <code>&amp;T</code>, and <code>&amp;mut T</code> are all infinite sets, since it's possible to borrow a type ad-infinitum. <code>T</code> is a superset of both <code>&amp;T</code> and <code>&amp;mut T</code>. <code>&amp;T</code> and <code>&amp;mut T</code> are disjoint sets. Here's a couple examples which validate these concepts:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Trait {}

impl&lt;T&gt; Trait for T {}

impl&lt;T&gt; Trait for &amp;T {} // ❌

impl&lt;T&gt; Trait for &amp;mut T {} // ❌
<span class="boring">}
</span></code></pre></pre>
<p>The above program doesn't compile as expected:</p>
<pre><code class="language-none">error[E0119]: conflicting implementations of trait `Trait` for type `&amp;_`:
 --&gt; src/lib.rs:5:1
  |
3 | impl&lt;T&gt; Trait for T {}
  | ------------------- first implementation here
4 |
5 | impl&lt;T&gt; Trait for &amp;T {}
  | ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&amp;_`

error[E0119]: conflicting implementations of trait `Trait` for type `&amp;mut _`:
 --&gt; src/lib.rs:7:1
  |
3 | impl&lt;T&gt; Trait for T {}
  | ------------------- first implementation here
...
7 | impl&lt;T&gt; Trait for &amp;mut T {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&amp;mut _`
</code></pre>
<p>The compiler doesn't allow us to define an implementation of <code>Trait</code> for <code>&amp;T</code> and <code>&amp;mut T</code> since it would conflict with the implementation of <code>Trait</code> for <code>T</code> which already includes all of <code>&amp;T</code> and <code>&amp;mut T</code>. The program below compiles as expected, since <code>&amp;T</code> and <code>&amp;mut T</code> are disjoint:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Trait {}

impl&lt;T&gt; Trait for &amp;T {} // ✅

impl&lt;T&gt; Trait for &amp;mut T {} // ✅
<span class="boring">}
</span></code></pre></pre>
<p><strong>Key Takeaways</strong></p>
<ul>
<li><code>T</code> is a superset of both <code>&amp;T</code> and <code>&amp;mut T</code></li>
<li><code>&amp;T</code> and <code>&amp;mut T</code> are disjoint sets</li>
</ul>
<h3 id="2-if-t-static-then-t-must-be-valid-for-the-entire-program"><a class="header" href="#2-if-t-static-then-t-must-be-valid-for-the-entire-program">2) if <code>T: 'static</code> then <code>T</code> must be valid for the entire program</a></h3>
<p><strong>Misconception Corollaries</strong></p>
<ul>
<li><code>T: 'static</code> should be read as <em>&quot;<code>T</code> has a <code>'static</code> lifetime&quot;</em></li>
<li><code>&amp;'static T</code> and <code>T: 'static</code> are the same thing</li>
<li>if <code>T: 'static</code> then <code>T</code> must be immutable</li>
<li>if <code>T: 'static</code> then <code>T</code> can only be created at compile time</li>
</ul>
<p>Most Rust beginners get introduced to the <code>'static</code> lifetime for the first time in a code example that looks something like this:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let str_literal: &amp;'static str = &quot;str literal&quot;;
}
</code></pre></pre>
<p>They get told that <code>&quot;str literal&quot;</code> is hardcoded into the compiled binary and is loaded into read-only memory at run-time so it's immutable and valid for the entire program and that's what makes it <code>'static</code>. These concepts are further reinforced by the rules surrounding defining <code>static</code> variables using the <code>static</code> keyword.</p>
<pre><pre class="playground"><code class="language-rust">// Note: This example is purely for illustrative purposes.
// Never use `static mut`. It's a footgun. There are
// safe patterns for global mutable singletons in Rust but
// those are outside the scope of this article.

static BYTES: [u8; 3] = [1, 2, 3];
static mut MUT_BYTES: [u8; 3] = [1, 2, 3];

fn main() {
   MUT_BYTES[0] = 99; // ❌ - mutating static is unsafe

    unsafe {
        MUT_BYTES[0] = 99;
        assert_eq!(99, MUT_BYTES[0]);
    }
}
</code></pre></pre>
<p>Regarding <code>static</code> variables</p>
<ul>
<li>they can only be created at compile-time</li>
<li>they should be immutable, mutating them is unsafe</li>
<li>they're valid for the entire program</li>
</ul>
<p>The <code>'static</code> lifetime was probably named after the default lifetime of <code>static</code> variables, right? So it makes sense that the <code>'static</code> lifetime has to follow all the same rules, right?</p>
<p>Well yes, but a type <em>with</em> a <code>'static</code> lifetime is different from a type <em>bounded by</em> a <code>'static</code> lifetime. The latter can be dynamically allocated at run-time, can be safely and freely mutated, can be dropped, and can live for arbitrary durations.</p>
<p>It's important at this point to distinguish <code>&amp;'static T</code> from <code>T: 'static</code>.</p>
<p><code>&amp;'static T</code> is an immutable reference to some <code>T</code> that can be safely held indefinitely long, including up until the end of the program. This is only possible if <code>T</code> itself is immutable and does not move <em>after the reference was created</em>. <code>T</code> does not need to be created at compile-time. It's possible to generate random dynamically allocated data at run-time and return <code>'static</code> references to it via a memory leak, e.g.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use rand;

// generate random 'static str refs at run-time
fn rand_str_generator() -&gt; &amp;'static str {
    let rand_string = rand::random::&lt;u64&gt;().to_string();
    Box::leak(rand_string.into_boxed_str())
}
<span class="boring">}
</span></code></pre></pre>
<p><code>T: 'static</code> is some <code>T</code> that can be safely held indefinitely long, including up until the end of the program. <code>T: 'static</code> includes all <code>&amp;'static T</code> however it also includes all owned types, like <code>String</code>, <code>Vec</code>, etc. The owner of some data is guaranteed that data will never get invalidated as long as the owner holds onto it, therefore the owner can safely hold onto the data indefinitely long, including up until the end of the program. <code>T: 'static</code> should be read as <em>&quot;<code>T</code> is bounded by a <code>'static</code> lifetime&quot;</em> not <em>&quot;<code>T</code> has a <code>'static</code> lifetime&quot;</em>. A program to help illustrate these concepts:</p>
<pre><pre class="playground"><code class="language-rust">use rand;

fn drop_static&lt;T: 'static&gt;(t: T) {
    std::mem::drop(t);
}

fn main() {
    let mut strings: Vec&lt;String&gt; = Vec::new();
    for _ in 0..10 {
        if rand::random() {
            // all the strings are randomly generated
            // and dynamically allocated at run-time
            let string = rand::random::&lt;u64&gt;().to_string();
            strings.push(string);
        }
    }

    // strings are owned types so they're bounded by 'static
    for mut string in strings {
        // all the strings are mutable
        string.push_str(&quot;a mutation&quot;);
        // all the strings are droppable
        drop_static(string); // ✅
    }

    // all the strings have been invalidated before the end of the program
    println!(&quot;I am the end of the program&quot;);
}
</code></pre></pre>
<p><strong>Key Takeaways</strong></p>
<ul>
<li><code>T: 'static</code> should be read as <em>&quot;<code>T</code> is bounded by a <code>'static</code> lifetime&quot;</em></li>
<li>if <code>T: 'static</code> then <code>T</code> can be a borrowed type with a <code>'static</code> lifetime <em>or</em> an owned type</li>
<li>since <code>T: 'static</code> includes owned types that means <code>T</code>
<ul>
<li>can be dynamically allocated at run-time</li>
<li>does not have to be valid for the entire program</li>
<li>can be safely and freely mutated</li>
<li>can be dynamically dropped at run-time</li>
<li>can have lifetimes of different durations</li>
</ul>
</li>
</ul>
<h3 id="3-a-t-and-t-a-are-the-same-thing"><a class="header" href="#3-a-t-and-t-a-are-the-same-thing">3) <code>&amp;'a T</code> and <code>T: 'a</code> are the same thing</a></h3>
<p>This misconception is a generalized version of the one above.</p>
<p><code>&amp;'a T</code> requires and implies <code>T: 'a</code> since a reference to <code>T</code> of lifetime <code>'a</code> cannot be valid for <code>'a</code> if <code>T</code> itself is not valid for <code>'a</code>. For example, the Rust compiler will never allow the construction of the type <code>&amp;'static Ref&lt;'a, T&gt;</code> because if <code>Ref</code> is only valid for <code>'a</code> we can't make a <code>'static</code> reference to it.</p>
<p><code>T: 'a</code> includes all <code>&amp;'a T</code> but the reverse is not true.</p>
<pre><pre class="playground"><code class="language-rust">// only takes ref types bounded by 'a
fn t_ref&lt;'a, T: 'a&gt;(t: &amp;'a T) {}

// takes any types bounded by 'a
fn t_bound&lt;'a, T: 'a&gt;(t: T) {}

// owned type which contains a reference
struct Ref&lt;'a, T: 'a&gt;(&amp;'a T);

fn main() {
    let string = String::from(&quot;string&quot;);

    t_bound(&amp;string); // ✅
    t_bound(Ref(&amp;string)); // ✅
    t_bound(&amp;Ref(&amp;string)); // ✅

    t_ref(&amp;string); // ✅
    t_ref(Ref(&amp;string)); // ❌ - expected ref, found struct
    t_ref(&amp;Ref(&amp;string)); // ✅

    // string var is bounded by 'static which is bounded by 'a
    t_bound(string); // ✅
}
</code></pre></pre>
<p><strong>Key Takeaways</strong></p>
<ul>
<li><code>T: 'a</code> is more general and more flexible than <code>&amp;'a T</code></li>
<li><code>T: 'a</code> accepts owned types, owned types which contain references, and references</li>
<li><code>&amp;'a T</code> only accepts references</li>
<li>if <code>T: 'static</code> then <code>T: 'a</code> since <code>'static</code> &gt;= <code>'a</code> for all <code>'a</code></li>
</ul>
<h3 id="4-my-code-isnt-generic-and-doesnt-have-lifetimes"><a class="header" href="#4-my-code-isnt-generic-and-doesnt-have-lifetimes">4) my code isn't generic and doesn't have lifetimes</a></h3>
<p><strong>Misconception Corollaries</strong></p>
<ul>
<li>it's possible to avoid using generics and lifetimes</li>
</ul>
<p>This comforting misconception is kept alive thanks to Rust's lifetime elision rules, which allow you to omit lifetime annotations in functions because the Rust borrow checker will infer them following these rules:</p>
<ul>
<li>every input ref to a function gets a distinct lifetime</li>
<li>if there's exactly one input lifetime it gets applied to all output refs</li>
<li>if there's multiple input lifetimes but one of them is <code>&amp;self</code> or <code>&amp;mut self</code> then the lifetime of <code>self</code> is applied to all output refs</li>
<li>otherwise output lifetimes have to be made explicit</li>
</ul>
<p>That's a lot to take in so let's look at some examples:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// elided
fn print(s: &amp;str);

// expanded
fn print&lt;'a&gt;(s: &amp;'a str);

// elided
fn trim(s: &amp;str) -&gt; &amp;str;

// expanded
fn trim&lt;'a&gt;(s: &amp;'a str) -&gt; &amp;'a str;

// illegal, can't determine output lifetime, no inputs
fn get_str() -&gt; &amp;str;

// explicit options include
fn get_str&lt;'a&gt;() -&gt; &amp;'a str; // generic version
fn get_str() -&gt; &amp;'static str; // 'static version

// illegal, can't determine output lifetime, multiple inputs
fn overlap(s: &amp;str, t: &amp;str) -&gt; &amp;str;

// explicit (but still partially elided) options include
fn overlap&lt;'a&gt;(s: &amp;'a str, t: &amp;str) -&gt; &amp;'a str; // output can't outlive s
fn overlap&lt;'a&gt;(s: &amp;str, t: &amp;'a str) -&gt; &amp;'a str; // output can't outlive t
fn overlap&lt;'a&gt;(s: &amp;'a str, t: &amp;'a str) -&gt; &amp;'a str; // output can't outlive s &amp; t
fn overlap(s: &amp;str, t: &amp;str) -&gt; &amp;'static str; // output can outlive s &amp; t
fn overlap&lt;'a&gt;(s: &amp;str, t: &amp;str) -&gt; &amp;'a str; // no relationship between input &amp; output lifetimes

// expanded
fn overlap&lt;'a, 'b&gt;(s: &amp;'a str, t: &amp;'b str) -&gt; &amp;'a str;
fn overlap&lt;'a, 'b&gt;(s: &amp;'a str, t: &amp;'b str) -&gt; &amp;'b str;
fn overlap&lt;'a&gt;(s: &amp;'a str, t: &amp;'a str) -&gt; &amp;'a str;
fn overlap&lt;'a, 'b&gt;(s: &amp;'a str, t: &amp;'b str) -&gt; &amp;'static str;
fn overlap&lt;'a, 'b, 'c&gt;(s: &amp;'a str, t: &amp;'b str) -&gt; &amp;'c str;

// elided
fn compare(&amp;self, s: &amp;str) -&gt; &amp;str;

// expanded
fn compare&lt;'a, 'b&gt;(&amp;'a self, &amp;'b str) -&gt; &amp;'a str;
<span class="boring">}
</span></code></pre></pre>
<p>If you've ever written</p>
<ul>
<li>a struct method</li>
<li>a function which takes references</li>
<li>a function which returns references</li>
<li>a generic function</li>
<li>a trait object (more on this later)</li>
<li>a closure (more on this later)</li>
</ul>
<p>then your code has generic elided lifetime annotations all over it.</p>
<p><strong>Key Takeaways</strong></p>
<ul>
<li>almost all Rust code is generic code and there's elided lifetime annotations everywhere</li>
</ul>
<h3 id="5-if-it-compiles-then-my-lifetime-annotations-are-correct"><a class="header" href="#5-if-it-compiles-then-my-lifetime-annotations-are-correct">5) if it compiles then my lifetime annotations are correct</a></h3>
<p><strong>Misconception Corollaries</strong></p>
<ul>
<li>Rust's lifetime elision rules for functions are always right</li>
<li>Rust's borrow checker is always right, technically <em>and semantically</em></li>
<li>Rust knows more about the semantics of my program than I do</li>
</ul>
<p>It's possible for a Rust program to be technically compilable but still semantically wrong. Take this for example:</p>
<pre><pre class="playground"><code class="language-rust">struct ByteIter&lt;'a&gt; {
    remainder: &amp;'a [u8]
}

impl&lt;'a&gt; ByteIter&lt;'a&gt; {
    fn next(&amp;mut self) -&gt; Option&lt;&amp;u8&gt; {
        if self.remainder.is_empty() {
            None
        } else {
            let byte = &amp;self.remainder[0];
            self.remainder = &amp;self.remainder[1..];
            Some(byte)
        }
    }
}

fn main() {
    let mut bytes = ByteIter { remainder: b&quot;1&quot; };
    assert_eq!(Some(&amp;b'1'), bytes.next());
    assert_eq!(None, bytes.next());
}
</code></pre></pre>
<p><code>ByteIter</code> is an iterator that iterates over a slice of bytes. We're skipping the <code>Iterator</code> trait implementation for conciseness. It seems to work fine, but what if we want to check a couple bytes at a time?</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let mut bytes = ByteIter { remainder: b&quot;1123&quot; };
    let byte_1 = bytes.next();
    let byte_2 = bytes.next();
    if byte_1 == byte_2 { // ❌
        // do something
    }
}
</code></pre></pre>
<p>Uh oh! Compile error:</p>
<pre><code class="language-none">error[E0499]: cannot borrow `bytes` as mutable more than once at a time
  --&gt; src/main.rs:20:18
   |
19 |     let byte_1 = bytes.next();
   |                  ----- first mutable borrow occurs here
20 |     let byte_2 = bytes.next();
   |                  ^^^^^ second mutable borrow occurs here
21 |     if byte_1 == byte_2 {
   |        ------ first borrow later used here
</code></pre>
<p>I guess we can copy each byte. Copying is okay when we're working with bytes but if we turned <code>ByteIter</code> into a generic slice iterator that can iterate over any <code>&amp;'a [T]</code> then we might want to use it in the future with types that may be very expensive or impossible to copy and clone. Oh well, I guess there's nothing we can do about that, the code compiles so the lifetime annotations must be right, right?</p>
<p>Nope, the current lifetime annotations are actually the source of the bug! It's particularly hard to spot because the buggy lifetime annotations are elided. Let's expand the elided lifetimes to get a clearer look at the problem:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct ByteIter&lt;'a&gt; {
    remainder: &amp;'a [u8]
}

impl&lt;'a&gt; ByteIter&lt;'a&gt; {
    fn next&lt;'b&gt;(&amp;'b mut self) -&gt; Option&lt;&amp;'b u8&gt; {
        if self.remainder.is_empty() {
            None
        } else {
            let byte = &amp;self.remainder[0];
            self.remainder = &amp;self.remainder[1..];
            Some(byte)
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>That didn't help at all. I'm still confused. Here's a hot tip that only Rust pros know: give your lifetime annotations descriptive names. Let's try again:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct ByteIter&lt;'remainder&gt; {
    remainder: &amp;'remainder [u8]
}

impl&lt;'remainder&gt; ByteIter&lt;'remainder&gt; {
    fn next&lt;'mut_self&gt;(&amp;'mut_self mut self) -&gt; Option&lt;&amp;'mut_self u8&gt; {
        if self.remainder.is_empty() {
            None
        } else {
            let byte = &amp;self.remainder[0];
            self.remainder = &amp;self.remainder[1..];
            Some(byte)
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Each returned byte is annotated with <code>'mut_self</code> but the bytes are clearly coming from <code>'remainder</code>! Let's fix it.</p>
<pre><pre class="playground"><code class="language-rust">struct ByteIter&lt;'remainder&gt; {
    remainder: &amp;'remainder [u8]
}

impl&lt;'remainder&gt; ByteIter&lt;'remainder&gt; {
    fn next(&amp;mut self) -&gt; Option&lt;&amp;'remainder u8&gt; {
        if self.remainder.is_empty() {
            None
        } else {
            let byte = &amp;self.remainder[0];
            self.remainder = &amp;self.remainder[1..];
            Some(byte)
        }
    }
}

fn main() {
    let mut bytes = ByteIter { remainder: b&quot;1123&quot; };
    let byte_1 = bytes.next();
    let byte_2 = bytes.next();
    std::mem::drop(bytes); // we can even drop the iterator now!
    if byte_1 == byte_2 { // ✅
        // do something
    }
}
</code></pre></pre>
<p>Now that we look back on the previous version of our program it was obviously wrong, so why did Rust compile it? The answer is simple: it was memory safe.</p>
<p>The Rust borrow checker only cares about the lifetime annotations in a program to the extent it can use them to statically verify the memory safety of the program. Rust will happily compile programs even if the lifetime annotations have semantic errors, and the consequence of this is that the program becomes unnecessarily restrictive.</p>
<p>Here's a quick example that's the opposite of the previous example: Rust's lifetime elision rules happen to be semantically correct in this instance but we unintentionally write a very restrictive method with our own unnecessary explicit lifetime annotations.</p>
<pre><pre class="playground"><code class="language-rust">#[derive(Debug)]
struct NumRef&lt;'a&gt;(&amp;'a i32);

impl&lt;'a&gt; NumRef&lt;'a&gt; {
    // my struct is generic over 'a so that means I need to annotate
    // my self parameters with 'a too, right? (answer: no, not right)
    fn some_method(&amp;'a mut self) {}
}

fn main() {
    let mut num_ref = NumRef(&amp;5);
    num_ref.some_method(); // mutably borrows num_ref for the rest of its lifetime
    num_ref.some_method(); // ❌
    println!(&quot;{:?}&quot;, num_ref); // ❌
}
</code></pre></pre>
<p>If we have some struct generic over <code>'a</code> we almost never want to write a method with a <code>&amp;'a mut self</code> receiver. What we're communicating to Rust is <em>&quot;this method will mutably borrow the struct for the entirety of the struct's lifetime&quot;</em>. In practice this means Rust's borrow checker will only allow at most one call to <code>some_method</code> before the struct becomes permanently mutably borrowed and thus unusable. The use-cases for this are extremely rare but the code above is very easy for confused beginners to write and it compiles. The fix is to not add unnecessary explicit lifetime annotations and let Rust's lifetime elision rules handle it:</p>
<pre><pre class="playground"><code class="language-rust">#[derive(Debug)]
struct NumRef&lt;'a&gt;(&amp;'a i32);

impl&lt;'a&gt; NumRef&lt;'a&gt; {
    // no more 'a on mut self
    fn some_method(&amp;mut self) {}

    // above line desugars to
    fn some_method_desugared&lt;'b&gt;(&amp;'b mut self){}
}

fn main() {
    let mut num_ref = NumRef(&amp;5);
    num_ref.some_method();
    num_ref.some_method(); // ✅
    println!(&quot;{:?}&quot;, num_ref); // ✅
}
</code></pre></pre>
<p><strong>Key Takeaways</strong></p>
<ul>
<li>Rust's lifetime elision rules for functions are not always right for every situation</li>
<li>Rust does not know more about the semantics of your program than you do</li>
<li>give your lifetime annotations descriptive names</li>
<li>try to be mindful of where you place explicit lifetime annotations and why</li>
</ul>
<h3 id="6-boxed-trait-objects-dont-have-lifetimes"><a class="header" href="#6-boxed-trait-objects-dont-have-lifetimes">6) boxed trait objects don't have lifetimes</a></h3>
<p>Earlier we discussed Rust's lifetime elision rules <em>for functions</em>. Rust also has lifetime elision rules for trait objects, which are:</p>
<ul>
<li>if a trait object is used as a type argument to a generic type then its life bound is inferred from the containing type
<ul>
<li>if there's a unique bound from the containing then that's used</li>
<li>if there's more than one bound from the containing type then an explicit bound must be specified</li>
</ul>
</li>
<li>if the above doesn't apply then
<ul>
<li>if the trait is defined with a single lifetime bound then that bound is used</li>
<li>if <code>'static</code> is used for any lifetime bound then <code>'static</code> is used</li>
<li>if the trait has no lifetime bounds then its lifetime is inferred in expressions and is <code>'static</code> outside of expressions</li>
</ul>
</li>
</ul>
<p>All of that sounds super complicated but can be simply summarized as <em>&quot;a trait object's lifetime bound is inferred from context.&quot;</em> After looking at a handful of examples we'll see the lifetime bound inferences are pretty intuitive so we don't have to memorize the formal rules:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::cell::Ref;

trait Trait {}

// elided
type T1 = Box&lt;dyn Trait&gt;;
// expanded, Box&lt;T&gt; has no lifetime bound on T, so inferred as 'static
type T2 = Box&lt;dyn Trait + 'static&gt;;

// elided
impl dyn Trait {}
// expanded
impl dyn Trait + 'static {}

// elided
type T3&lt;'a&gt; = &amp;'a dyn Trait;
// expanded, &amp;'a T requires T: 'a, so inferred as 'a
type T4&lt;'a&gt; = &amp;'a (dyn Trait + 'a);

// elided
type T5&lt;'a&gt; = Ref&lt;'a, dyn Trait&gt;;
// expanded, Ref&lt;'a, T&gt; requires T: 'a, so inferred as 'a
type T6&lt;'a&gt; = Ref&lt;'a, dyn Trait + 'a&gt;;

trait GenericTrait&lt;'a&gt;: 'a {}

// elided
type T7&lt;'a&gt; = Box&lt;dyn GenericTrait&lt;'a&gt;&gt;;
// expanded
type T8&lt;'a&gt; = Box&lt;dyn GenericTrait&lt;'a&gt; + 'a&gt;;

// elided
impl&lt;'a&gt; dyn GenericTrait&lt;'a&gt; {}
// expanded
impl&lt;'a&gt; dyn GenericTrait&lt;'a&gt; + 'a {}
<span class="boring">}
</span></code></pre></pre>
<p>Concrete types which implement traits can have references and thus they also have lifetime bounds, and so their corresponding trait objects have lifetime bounds. Also you can implement traits directly for references which obviously have lifetime bounds:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Trait {}

struct Struct {}
struct Ref&lt;'a, T&gt;(&amp;'a T);

impl Trait for Struct {}
impl Trait for &amp;Struct {} // impl Trait directly on a ref type
impl&lt;'a, T&gt; Trait for Ref&lt;'a, T&gt; {} // impl Trait on a type containing refs
<span class="boring">}
</span></code></pre></pre>
<p>Anyway, this is worth going over because it often confuses beginners when they refactor a function from using trait objects to generics or vice versa. Take this program for example:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Display;

fn dynamic_thread_print(t: Box&lt;dyn Display + Send&gt;) {
    std::thread::spawn(move || {
        println!(&quot;{}&quot;, t);
    }).join();
}

fn static_thread_print&lt;T: Display + Send&gt;(t: T) { // ❌
    std::thread::spawn(move || {
        println!(&quot;{}&quot;, t);
    }).join();
}
<span class="boring">}
</span></code></pre></pre>
<p>It throws this compile error:</p>
<pre><code class="language-none">error[E0310]: the parameter type `T` may not live long enough
  --&gt; src/lib.rs:10:5
   |
9  | fn static_thread_print&lt;T: Display + Send&gt;(t: T) {
   |                        -- help: consider adding an explicit lifetime bound...: `T: 'static +`
10 |     std::thread::spawn(move || {
   |     ^^^^^^^^^^^^^^^^^^
   |
note: ...so that the type `[closure@src/lib.rs:10:24: 12:6 t:T]` will meet its required lifetime bounds
  --&gt; src/lib.rs:10:5
   |
10 |     std::thread::spawn(move || {
   |     ^^^^^^^^^^^^^^^^^^
</code></pre>
<p>Okay great, the compiler tells us how to fix the issue so let's fix the issue.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Display;

fn dynamic_thread_print(t: Box&lt;dyn Display + Send&gt;) {
    std::thread::spawn(move || {
        println!(&quot;{}&quot;, t);
    }).join();
}

fn static_thread_print&lt;T: Display + Send + 'static&gt;(t: T) { // ✅
    std::thread::spawn(move || {
        println!(&quot;{}&quot;, t);
    }).join();
}
<span class="boring">}
</span></code></pre></pre>
<p>It compiles now but these two functions look awkward next to each other, why does the second function require a <code>'static</code> bound on <code>T</code> where the first function doesn't? That's a trick question. Using the lifetime elision rules Rust automatically infers a <code>'static</code> bound in the first function so both actually have <code>'static</code> bounds. This is what the Rust compiler sees:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Display;

fn dynamic_thread_print(t: Box&lt;dyn Display + Send + 'static&gt;) {
    std::thread::spawn(move || {
        println!(&quot;{}&quot;, t);
    }).join();
}

fn static_thread_print&lt;T: Display + Send + 'static&gt;(t: T) {
    std::thread::spawn(move || {
        println!(&quot;{}&quot;, t);
    }).join();
}
<span class="boring">}
</span></code></pre></pre>
<p><strong>Key Takeaways</strong></p>
<ul>
<li>all trait objects have some inferred default lifetime bounds</li>
</ul>
<h3 id="7-compiler-error-messages-will-tell-me-how-to-fix-my-program"><a class="header" href="#7-compiler-error-messages-will-tell-me-how-to-fix-my-program">7) compiler error messages will tell me how to fix my program</a></h3>
<p><strong>Misconception Corollaries</strong></p>
<ul>
<li>Rust's lifetime elision rules for trait objects are always right</li>
<li>Rust knows more about the semantics of my program than I do</li>
</ul>
<p>This misconception is the previous two misconceptions combined into one example:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Display;

fn box_displayable&lt;T: Display&gt;(t: T) -&gt; Box&lt;dyn Display&gt; { // ❌
    Box::new(t)
}
<span class="boring">}
</span></code></pre></pre>
<p>Throws this error:</p>
<pre><code class="language-none">error[E0310]: the parameter type `T` may not live long enough
 --&gt; src/lib.rs:4:5
  |
3 | fn box_displayable&lt;T: Display&gt;(t: T) -&gt; Box&lt;dyn Display&gt; {
  |                    -- help: consider adding an explicit lifetime bound...: `T: 'static +`
4 |     Box::new(t)
  |     ^^^^^^^^^^^
  |
note: ...so that the type `T` will meet its required lifetime bounds
 --&gt; src/lib.rs:4:5
  |
4 |     Box::new(t)
  |     ^^^^^^^^^^^
</code></pre>
<p>Okay, let's fix it how the compiler is telling us to fix it, nevermind the fact that it's automatically inferring a <code>'static</code> lifetime bound for our boxed trait object without telling us and its recommended fix is based on that unstated fact:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Display;

fn box_displayable&lt;T: Display + 'static&gt;(t: T) -&gt; Box&lt;dyn Display&gt; { // ✅
    Box::new(t)
}
<span class="boring">}
</span></code></pre></pre>
<p>So the program compiles now... but is this what we actually want? Probably, but maybe not. The compiler didn't mention any other fixes but this would have also been appropriate:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Display;

fn box_displayable&lt;'a, T: Display + 'a&gt;(t: T) -&gt; Box&lt;dyn Display + 'a&gt; { // ✅
    Box::new(t)
}
<span class="boring">}
</span></code></pre></pre>
<p>This function accepts all the same arguments as the previous version plus a lot more! Does that make it better? Not necessarily, it depends on the requirements and constraints of our program. This example is a bit abstract so let's take a look at a simpler and more obvious case:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn return_first(a: &amp;str, b: &amp;str) -&gt; &amp;str { // ❌
    a
}
<span class="boring">}
</span></code></pre></pre>
<p>Throws:</p>
<pre><code class="language-none">error[E0106]: missing lifetime specifier
 --&gt; src/lib.rs:1:38
  |
1 | fn return_first(a: &amp;str, b: &amp;str) -&gt; &amp;str {
  |                    ----     ----     ^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a` or `b`
help: consider introducing a named lifetime parameter
  |
1 | fn return_first&lt;'a&gt;(a: &amp;'a str, b: &amp;'a str) -&gt; &amp;'a str {
  |                ^^^^    ^^^^^^^     ^^^^^^^     ^^^
</code></pre>
<p>The error message recommends annotating both inputs and the output with the same lifetime. If we did this our program would compile but this function would overly-constrain the return type. What we actually want is this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn return_first&lt;'a&gt;(a: &amp;'a str, b: &amp;str) -&gt; &amp;'a str { // ✅
    a
}
<span class="boring">}
</span></code></pre></pre>
<p><strong>Key Takeaways</strong></p>
<ul>
<li>Rust's lifetime elision rules for trait objects are not always right for every situation</li>
<li>Rust does not know more about the semantics of your program than you do</li>
<li>Rust compiler error messages suggest fixes which will make your program compile which is not that same as fixes which will make you program compile <em>and</em> best suit the requirements of your program</li>
</ul>
<h3 id="8-lifetimes-can-grow-and-shrink-at-run-time"><a class="header" href="#8-lifetimes-can-grow-and-shrink-at-run-time">8) lifetimes can grow and shrink at run-time</a></h3>
<p><strong>Misconception Corollaries</strong></p>
<ul>
<li>container types can swap references at run-time to change their lifetime</li>
<li>Rust borrow checker does advanced control flow analysis</li>
</ul>
<p>This does not compile:</p>
<pre><pre class="playground"><code class="language-rust">struct Has&lt;'lifetime&gt; {
    lifetime: &amp;'lifetime str,
}

fn main() {
    let long = String::from(&quot;long&quot;);
    let mut has = Has { lifetime: &amp;long };
    assert_eq!(has.lifetime, &quot;long&quot;);

    {
        let short = String::from(&quot;short&quot;);
        // &quot;switch&quot; to short lifetime
        has.lifetime = &amp;short;
        assert_eq!(has.lifetime, &quot;short&quot;);

        // &quot;switch back&quot; to long lifetime (but not really)
        has.lifetime = &amp;long;
        assert_eq!(has.lifetime, &quot;long&quot;);
        // `short` dropped here
    }

    assert_eq!(has.lifetime, &quot;long&quot;); // ❌ - `short` still &quot;borrowed&quot; after drop
}
</code></pre></pre>
<p>It throws:</p>
<pre><code class="language-none">error[E0597]: `short` does not live long enough
  --&gt; src/main.rs:11:24
   |
11 |         has.lifetime = &amp;short;
   |                        ^^^^^^ borrowed value does not live long enough
...
15 |     }
   |     - `short` dropped here while still borrowed
16 |     assert_eq!(has.lifetime, &quot;long&quot;);
   |     --------------------------------- borrow later used here
</code></pre>
<p>This also does not compile, throws the exact same error as above:</p>
<pre><pre class="playground"><code class="language-rust">struct Has&lt;'lifetime&gt; {
    lifetime: &amp;'lifetime str,
}

fn main() {
    let long = String::from(&quot;long&quot;);
    let mut has = Has { lifetime: &amp;long };
    assert_eq!(has.lifetime, &quot;long&quot;);

    // this block will never run
    if false {
        let short = String::from(&quot;short&quot;);
        // &quot;switch&quot; to short lifetime
        has.lifetime = &amp;short;
        assert_eq!(has.lifetime, &quot;short&quot;);

        // &quot;switch back&quot; to long lifetime (but not really)
        has.lifetime = &amp;long;
        assert_eq!(has.lifetime, &quot;long&quot;);
        // `short` dropped here
    }

    assert_eq!(has.lifetime, &quot;long&quot;); // ❌ - `short` still &quot;borrowed&quot; after drop
}
</code></pre></pre>
<p>Lifetimes have to be statically verified at compile-time and the Rust borrow checker only does very basic control flow analysis, so it assumes every block in an <code>if-else</code> statement and every match arm in a <code>match</code> statement can be taken and then chooses the shortest possible lifetime for the variable. Once a variable is bounded by a lifetime it is bounded by that lifetime <em>forever</em>. The lifetime of a variable can only shrink, and all the shrinkage is determined at compile-time.</p>
<p><strong>Key Takeaways</strong></p>
<ul>
<li>lifetimes are statically verified at compile-time</li>
<li>lifetimes cannot grow or shrink or change in any way at run-time</li>
<li>Rust borrow checker will always choose the shortest possible lifetime for a variable assuming all code paths can be taken</li>
</ul>
<h3 id="9-downgrading-mut-refs-to-shared-refs-is-safe"><a class="header" href="#9-downgrading-mut-refs-to-shared-refs-is-safe">9) downgrading mut refs to shared refs is safe</a></h3>
<p><strong>Misconception Corollaries</strong></p>
<ul>
<li>re-borrowing a reference ends its lifetime and starts a new one</li>
</ul>
<p>You can pass a mut ref to a function expecting a shared ref because Rust will implicitly re-borrow the mut ref as immutable:</p>
<pre><pre class="playground"><code class="language-rust">fn takes_shared_ref(n: &amp;i32) {}

fn main() {
    let mut a = 10;
    takes_shared_ref(&amp;mut a); // ✅
    takes_shared_ref(&amp;*(&amp;mut a)); // above line desugared
}
</code></pre></pre>
<p>Intuitively this makes sense, since there's no harm in re-borrowing a mut ref as immutable, right? Surprisingly no, as the program below does not compile:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let mut a = 10;
    let b: &amp;i32 = &amp;*(&amp;mut a); // re-borrowed as immutable
    let c: &amp;i32 = &amp;a;
    dbg!(b, c); // ❌
}
</code></pre></pre>
<p>Throws this error:</p>
<pre><code class="language-none">error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
 --&gt; src/main.rs:4:19
  |
3 |     let b: &amp;i32 = &amp;*(&amp;mut a);
  |                     -------- mutable borrow occurs here
4 |     let c: &amp;i32 = &amp;a;
  |                   ^^ immutable borrow occurs here
5 |     dbg!(b, c);
  |          - mutable borrow later used here
</code></pre>
<p>A mutable borrow does occur, but it's immediately and unconditionally re-borrowed as immutable and then dropped. Why is Rust treating the immutable re-borrow as if it still has the mut ref's exclusive lifetime? While there's no issue in the particular example above, allowing the ability to downgrade mut refs to shared refs does indeed introduce potential memory safety issues:</p>
<pre><pre class="playground"><code class="language-rust">use std::sync::Mutex;

struct Struct {
    mutex: Mutex&lt;String&gt;
}

impl Struct {
    // downgrades mut self to shared str
    fn get_string(&amp;mut self) -&gt; &amp;str {
        self.mutex.get_mut().unwrap()
    }
    fn mutate_string(&amp;self) {
        // if Rust allowed downgrading mut refs to shared refs
        // then the following line would invalidate any shared
        // refs returned from the get_string method
        *self.mutex.lock().unwrap() = &quot;surprise!&quot;.to_owned();
    }
}

fn main() {
    let mut s = Struct {
        mutex: Mutex::new(&quot;string&quot;.to_owned())
    };
    let str_ref = s.get_string(); // mut ref downgraded to shared ref
    s.mutate_string(); // str_ref invalidated, now a dangling pointer
    dbg!(str_ref); // ❌ - as expected!
}
</code></pre></pre>
<p>The point here is that when you re-borrow a mut ref as a shared ref you don't get that shared ref without a big gotcha: it extends the mut ref's lifetime for the duration of the re-borrow even if the mut ref itself is dropped. Using the re-borrowed shared ref is very difficult because it's immutable but it can't overlap with any other shared refs. The re-borrowed shared ref has all the cons of a mut ref and all the cons of a shared ref and has the pros of neither. I believe re-borrowing a mut ref as a shared ref should be considered a Rust anti-pattern. Being aware of this anti-pattern is important so that you can easily spot it when you see code like this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// downgrades mut T to shared T
fn some_function&lt;T&gt;(some_arg: &amp;mut T) -&gt; &amp;T;

struct Struct;

impl Struct {
    // downgrades mut self to shared self
    fn some_method(&amp;mut self) -&gt; &amp;Self;

    // downgrades mut self to shared T
    fn other_method(&amp;mut self) -&gt; &amp;T;
}
<span class="boring">}
</span></code></pre></pre>
<p>Even if you avoid re-borrows in function and method signatures Rust still does automatic implicit re-borrows so it's easy to bump into this problem without realizing it like so:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::collections::HashMap;

type PlayerID = i32;

#[derive(Debug, Default)]
struct Player {
    score: i32,
}

fn start_game(player_a: PlayerID, player_b: PlayerID, server: &amp;mut HashMap&lt;PlayerID, Player&gt;) {
    // get players from server or create &amp; insert new players if they don't yet exist
    let player_a: &amp;Player = server.entry(player_a).or_default();
    let player_b: &amp;Player = server.entry(player_b).or_default();

    // do something with players
    dbg!(player_a, player_b); // ❌
}
<span class="boring">}
</span></code></pre></pre>
<p>The above fails to compile. <code>or_default()</code> returns a <code>&amp;mut Player</code> which we're implicitly re-borrowing as <code>&amp;Player</code> because of our explicit type annotations. To do what we want we have to:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::collections::HashMap;

type PlayerID = i32;

#[derive(Debug, Default)]
struct Player {
    score: i32,
}

fn start_game(player_a: PlayerID, player_b: PlayerID, server: &amp;mut HashMap&lt;PlayerID, Player&gt;) {
    // drop the returned mut Player refs since we can't use them together anyway
    server.entry(player_a).or_default();
    server.entry(player_b).or_default();

    // fetch the players again, getting them immutably this time, without any implicit re-borrows
    let player_a = server.get(&amp;player_a);
    let player_b = server.get(&amp;player_b);

    // do something with players
    dbg!(player_a, player_b); // ✅
}
<span class="boring">}
</span></code></pre></pre>
<p>Kinda awkward and clunky but this is the sacrifice we make at the Altar of Memory Safety.</p>
<p><strong>Key Takeaways</strong></p>
<ul>
<li>try not to re-borrow mut refs as shared refs, or you're gonna have a bad time</li>
<li>re-borrowing a mut ref doesn't end its lifetime, even if the ref is dropped</li>
</ul>
<h3 id="10-closures-follow-the-same-lifetime-elision-rules-as-functions"><a class="header" href="#10-closures-follow-the-same-lifetime-elision-rules-as-functions">10) closures follow the same lifetime elision rules as functions</a></h3>
<p>This is more of a Rust Gotcha than a misconception.</p>
<p>Closures, despite being functions, do not follow the same lifetime elision rules as functions.</p>
<pre><pre class="playground"><code class="language-rust">fn function(x: &amp;i32) -&gt; &amp;i32 {
    x
}

fn main() {
    let closure = |x: &amp;i32| x; // ❌
}
</code></pre></pre>
<p>Throws:</p>
<pre><code class="language-none">error: lifetime may not live long enough
 --&gt; src/main.rs:6:29
  |
6 |     let closure = |x: &amp;i32| x;
  |                       -   - ^ returning this value requires that `'1` must outlive `'2`
  |                       |   |
  |                       |   return type of closure is &amp;'2 i32
  |                       let's call the lifetime of this reference `'1`
</code></pre>
<p>After desugaring we get:</p>
<pre><pre class="playground"><code class="language-rust">// input lifetime gets applied to output
fn function&lt;'a&gt;(x: &amp;'a i32) -&gt; &amp;'a i32 {
    x
}

fn main() {
    // input and output each get their own distinct lifetimes
    let closure = for&lt;'a, 'b&gt; |x: &amp;'a i32| -&gt; &amp;'b i32 { x };
    // note: the above line is not valid syntax, but we need it for illustrative purposes
}
</code></pre></pre>
<p>There's no good reason for this discrepancy. Closures were first implemented with different type inference semantics than functions and now we're stuck with it forever because to unify them at this point would be a breaking change. So how can we explicitly annotate a closure's type? Our options include:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    // cast to trait object, becomes unsized, oops, compile error
    let identity: dyn Fn(&amp;i32) -&gt; &amp;i32 = |x: &amp;i32| x;

    // can allocate it on the heap as a workaround but feels clunky
    let identity: Box&lt;dyn Fn(&amp;i32) -&gt; &amp;i32&gt; = Box::new(|x: &amp;i32| x);

    // can skip the allocation and just create a static reference
    let identity: &amp;dyn Fn(&amp;i32) -&gt; &amp;i32 = &amp;|x: &amp;i32| x;

    // previous line desugared :)
    let identity: &amp;'static (dyn for&lt;'a&gt; Fn(&amp;'a i32) -&gt; &amp;'a i32 + 'static) = &amp;|x: &amp;i32| -&gt; &amp;i32 { x };

    // this would be ideal but it's invalid syntax
    let identity: impl Fn(&amp;i32) -&gt; &amp;i32 = |x: &amp;i32| x;

    // this would also be nice but it's also invalid syntax
    let identity = for&lt;'a&gt; |x: &amp;'a i32| -&gt; &amp;'a i32 { x };

    // since &quot;impl trait&quot; works in the function return position
    fn return_identity() -&gt; impl Fn(&amp;i32) -&gt; &amp;i32 {
        |x| x
    }
    let identity = return_identity();

    // more generic version of the previous solution
    fn annotate&lt;T, F&gt;(f: F) -&gt; F where F: Fn(&amp;T) -&gt; &amp;T {
        f
    }
    let identity = annotate(|x: &amp;i32| x);
}
</code></pre></pre>
<p>As I'm sure you've already noticed from the examples above, when closure types are used as trait bounds they do follow the usual function lifetime elision rules.</p>
<p>There's no real lesson or insight to be had here, it just is what it is.</p>
<p><strong>Key Takeaways</strong></p>
<ul>
<li>every language has gotchas 🤷</li>
</ul>
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
<ul>
<li><code>T</code> is a superset of both <code>&amp;T</code> and <code>&amp;mut T</code></li>
<li><code>&amp;T</code> and <code>&amp;mut T</code> are disjoint sets</li>
<li><code>T: 'static</code> should be read as <em>&quot;<code>T</code> is bounded by a <code>'static</code> lifetime&quot;</em></li>
<li>if <code>T: 'static</code> then <code>T</code> can be a borrowed type with a <code>'static</code> lifetime <em>or</em> an owned type</li>
<li>since <code>T: 'static</code> includes owned types that means <code>T</code>
<ul>
<li>can be dynamically allocated at run-time</li>
<li>does not have to be valid for the entire program</li>
<li>can be safely and freely mutated</li>
<li>can be dynamically dropped at run-time</li>
<li>can have lifetimes of different durations</li>
</ul>
</li>
<li><code>T: 'a</code> is more general and more flexible than <code>&amp;'a T</code></li>
<li><code>T: 'a</code> accepts owned types, owned types which contain references, and references</li>
<li><code>&amp;'a T</code> only accepts references</li>
<li>if <code>T: 'static</code> then <code>T: 'a</code> since <code>'static</code> &gt;= <code>'a</code> for all <code>'a</code></li>
<li>almost all Rust code is generic code and there's elided lifetime annotations everywhere</li>
<li>Rust's lifetime elision rules are not always right for every situation</li>
<li>Rust does not know more about the semantics of your program than you do</li>
<li>give your lifetime annotations descriptive names</li>
<li>try to be mindful of where you place explicit lifetime annotations and why</li>
<li>all trait objects have some inferred default lifetime bounds</li>
<li>Rust compiler error messages suggest fixes which will make your program compile which is not that same as fixes which will make you program compile <em>and</em> best suit the requirements of your program</li>
<li>lifetimes are statically verified at compile-time</li>
<li>lifetimes cannot grow or shrink or change in any way at run-time</li>
<li>Rust borrow checker will always choose the shortest possible lifetime for a variable assuming all code paths can be taken</li>
<li>try not to re-borrow mut refs as shared refs, or you're gonna have a bad time</li>
<li>re-borrowing a mut ref doesn't end its lifetime, even if the ref is dropped</li>
<li>every language has gotchas 🤷</li>
</ul>
<h2 id="discuss"><a class="header" href="#discuss">Discuss</a></h2>
<p>Discuss this article on</p>
<ul>
<li><a href="https://www.reddit.com/r/learnrust/comments/gmrcrq/common_rust_lifetime_misconceptions/">learnrust subreddit</a></li>
<li><a href="https://users.rust-lang.org/t/blog-post-common-rust-lifetime-misconceptions/42950">official Rust users forum</a></li>
<li><a href="https://twitter.com/pretzelhammer/status/1263505856903163910">Twitter</a></li>
<li><a href="https://www.reddit.com/r/rust/comments/golrsx/common_rust_lifetime_misconceptions/">rust subreddit</a></li>
<li><a href="https://news.ycombinator.com/item?id=23279731">Hackernews</a></li>
<li><a href="https://github.com/pretzelhammer/rust-blog/discussions">Github</a></li>
</ul>
<h2 id="notifications"><a class="header" href="#notifications">Notifications</a></h2>
<p>Get notified when the next article get published by</p>
<ul>
<li><a href="https://twitter.com/pretzelhammer">Following pretzelhammer on Twitter</a> or</li>
<li><a href="https://github.com/pretzelhammer/rust-blog/releases.atom">Subscribing to this repo's release RSS feed</a> or</li>
<li>Watching this repo's releases (click <code>Watch</code> -&gt; click <code>Custom</code> -&gt; select <code>Releases</code> -&gt; click <code>Apply</code>)</li>
</ul>
<h2 id="further-reading"><a class="header" href="#further-reading">Further Reading</a></h2>
<ul>
<li><a href="./sizedness-in-rust.html">Sizedness in Rust</a></li>
<li><a href="./tour-of-rusts-standard-library-traits.html">Tour of Rust's Standard Library Traits</a></li>
<li><a href="./restful-api-in-sync-and-async-rust.html">RESTful API in Sync &amp; Async Rust</a></li>
<li><a href="./learning-rust-in-2020.html">Learning Rust in 2020</a></li>
<li><a href="./too-many-brainfuck-compilers.html">Learn Assembly with Entirely Too Many Brainfuck Compilers</a></li>
</ul>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（2）/进击的Rust生命周期——一力降十会的MIR（2）.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next" href="../../02_生命周期/Rust生命周期常见误区/Rust生命周期常见误区.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（2）/进击的Rust生命周期——一力降十会的MIR（2）.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next" href="../../02_生命周期/Rust生命周期常见误区/Rust生命周期常见误区.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>




        <script type="text/javascript">
            window.playground_copyable = true;
        </script>


        <script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>

        <script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../book.js" type="text/javascript" charset="utf-8"></script>

        <!-- Custom JS scripts -->


    </body>
</html>
